package com.tiger.mgr 
{
	import com.adobe.utils.DictionaryUtil;
	import com.tiger.utils.EventListenerUtil;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.Dictionary;
	
	/**
	 * ...
	 * @author wmTiger
	 */
	public class ResMgr extends EventDispatcher 
	{
		private static var mInstance:ResMgr;
		
		private var mAssetRoot:String = "";// 设置全局加载文件的根目录
		private var mAssetDict:Dictionary;// 资源字典
		private var mSwfDict:Dictionary;// 载入的swf字典
		private var mPendingDict:Dictionary;// 所有载入的资源事件处理挂载字典
		private var mEvtListener:EventListenerUtil = new EventListenerUtil();
		
		public function ResMgr() 
		{
			mAssetDict = new Dictionary();
			mSwfDict = new Dictionary();
			mPendingDict = new Dictionary();
		}
		
		static public function get instance():ResMgr 
		{
			if (mInstance == null) 
			{
				mInstance = new ResMgr();
			}
			return mInstance;
		}
		
		/**
		 * 通过key获取swf文件中的根mc
		 * @param	key
		 * @return
		 */
		public function getSwf(key:String):MovieClip
		{
			var swf:MovieClip = mSwfDict[key];
			return swf;
		}
		
		/**
		 * 通过key以及类名字符串得到对应的类定义
		 * @param	key
		 * @param	clsName
		 * @return
		 */
		public function getClss(key:String, clsName:String):Class
		{
			var ref:Class;
			ref = ApplicationDomain.currentDomain.getDefinition(clsName) as Class;
			return ref;
		}
		
		/**
		 * 加载swf文件，加载完毕后，会将swf的根存入 mSwfDict
		 * @param	key			文件key，就是fileurl
		 * @param	fileurl		文件路径
		 * @param	completed	加载完成后
		 * @param	progress	加载中
		 */
		public function loadSwf(key:String, fileurl:String, completed:Function = null, progress:Function = null):void 
		{
			var swf:MovieClip = mSwfDict[key];
			if (swf == null) 
			{
				addPending(key, completed, progress);
				
				var loader:Loader = new Loader();
				var assetpath:String = getRandomPath(fileurl);
				initLoadSwfEvt(loader.contentLoaderInfo);
				var context:LoaderContext = new LoaderContext(true, ApplicationDomain.currentDomain);
				try 
				{
					//loader.load(new URLRequest(assetpath + getFileVersionString(fileurl)), context);
					loader.load(new URLRequest(assetpath), context);
				}
				catch (e : Error) 
				{
					trace("swf load error.");
				}
			}
			else
			{
				addPending(key, completed, progress);
				if (completed != null) 
				{
					completed();
				}
			}
		}
		
		private function initLoadSwfEvt(dispatcher:IEventDispatcher):void 
		{
			mEvtListener.addEventListener(dispatcher, Event.INIT, swfInitHandler);
			mEvtListener.addEventListener(dispatcher, ProgressEvent.PROGRESS, swfLoadProgress);
			loadResErr(dispatcher);
		}
		private function loadResErr(dispatcher:IEventDispatcher):void
		{
			mEvtListener.addEventListener(dispatcher, IOErrorEvent.IO_ERROR, loadError);
			mEvtListener.addEventListener(dispatcher, SecurityErrorEvent.SECURITY_ERROR, securityError);
		}
		
		private function loadError(e:IOErrorEvent):void 
		{
			mEvtListener.removeTargetAllEventListener(e.currentTarget as IEventDispatcher);
		}
		
		private function securityError(e:SecurityErrorEvent):void 
		{
			mEvtListener.removeTargetAllEventListener(e.currentTarget as IEventDispatcher);
		}
		
		private function swfInitHandler(e:Event):void 
		{
			mEvtListener.removeTargetAllEventListener(e.currentTarget as IEventDispatcher);
			
			var loader:Loader = e.currentTarget.loader as Loader;
			var key:String = getPendingKey(e.currentTarget.url);
			if (key.length > 0) 
			{
				doHandler(key, 1);
				mSwfDict[key] = MovieClip(loader.content);
			}
			loader.unloadAndStop();
		}
		
		// 执行对应key的函数,type = 1为completed, type = 2为progress
		private function doHandler(key:String, type:int = 0):void
		{
			if (key.length > 0) 
			{
				var func:Function = mPendingDict[key][type];
				if (func != null) 
				{
					func.call();
				}
			}
			else
			{
				trace("执行对应key的函数错误->",key);
			}
		}
		
		private function swfLoadProgress(e:ProgressEvent):void 
		{
			if (e.currentTarget.url) 
			{
				doHandler(getPendingKey(e.currentTarget.url), 2);
			}
		}
		
		private function getPendingKey(str:String):String
		{
			var arr:Array = DictionaryUtil.getKeys(mPendingDict);
			if (arr == null) 
			{
				return "";
			}
			var l:int = arr.length;
			for (var i:int = 0; i < l; i++) 
			{
				if (str.indexOf(arr[i]) > -1) 
				{
					return arr[i];
				}
			}
			return "";
		}
		
		private function addPending(key:String, completed:Function = null, progress:Function = null):void
		{
			var arr:Array = mPendingDict[key];
			if (arr == null) 
			{
				mPendingDict[key] = [key, completed, progress];
			}
			else
			{
				arr[1] = completed;
				arr[2] = progress;
			}
		}
		
		private function getRandomPath(fileurl:String):String
		{
			return mAssetRoot + fileurl + "?" + int(Math.random() * 10000000);
		}
		
		public function setAssetRoot(root : String) : void 
		{
			mAssetRoot = root; 
		}
		
		public function getAssetRoot() : String
		{
			return mAssetRoot;
		}
		
	}

}